package com.example.demo59hideusernotfoundexception.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.password.NoOpPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    PasswordEncoder passwordEncoder(){
        return NoOpPasswordEncoder.getInstance();
    }

    @Override
    @Bean
    protected UserDetailsService userDetailsService() {
        InMemoryUserDetailsManager us = new InMemoryUserDetailsManager();
        us.createUser(User.withUsername("wangnian").password("123").roles("admin").build());
        return us;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .anyRequest().authenticated()
                .and().formLogin()
                .failureHandler((request, response, exception) -> {
                    System.out.println(exception.toString());
                    response.getWriter().write("fail");
                })
                .and().csrf().disable();
    }

    /**
     * 自定义全局 AuthenticationManager，设置 hideUserNotFoundExceptions 为 false，表示暴露 UsernameNotFoundException 异常
     *
     * 除了使用自定义全局 AuthenticationManager来暴露 UsernameNotFoundException 异常
     * 最简单的做法是 自定义异常，在 userDetailsService#loadUserByUsername 的时候抛出来即可
     */
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
        provider.setUserDetailsService(userDetailsService());
        provider.setPasswordEncoder(passwordEncoder());
        // 表示不隐藏 UsernameNotFoundException 异常
        provider.setHideUserNotFoundExceptions(false);
        auth.authenticationProvider(provider);
    }
}
